



#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/ioctl.h>
#include <string.h>



#include "app.h"
#include "counter.h"
#include "config.h"

extern struct Config stConfig;
extern struct Config wkConfig;
int fd_counter = -1;


/**
//CPLD

Counter reg describe
reg[0]: ch1_divder_low	-> [w]
reg[1]: ch1_divder_high	-> [w]
reg[2]: ch1_divder_data -> [w]
reg[3]: channel1		-> [r+w]
reg[4]: ch2_divder_low  -> [w]
reg[5]: ch2_divder_high -> [w]
reg[6]: ch2_divder_data -> [w]
reg[7]: channel2		-> [r+w]
reg[8]: led		 		-> [r+w]
reg[9]: version			-> [r]

 **/

extern int CounterInit(void)
{

	unsigned char buf[5];


	fd_counter = open("/dev/counter",O_RDWR);
	if(-1 == fd_counter)
	{
		printf("[counter.c] do not open /dev/counter \n");
		return -1;
	}
	else
	{
		if(-1 == CounterReset())
		{
			printf("[counter.c] can not reset counter \n");
			return -1;
		}
		if(-1 == CounterVersion(&wkConfig) )
		{
			printf("[counter.c] verison read error \n");
			return -1;
		}				
		if(wkConfig.stCounterSet.u32EnableCh1 == ENABLE)
		{
			if(-1 == CounterSet(&wkConfig,CHANNEL1))
			{
				printf("[counter.c] channel1 set error \n");
				return -1;
			}
		}
		if(wkConfig.stCounterSet.u32EnableCh2 == ENABLE)
		{
			if(-1 == CounterSet(&wkConfig,CHANNEL2))
			{
				printf("[counter.c] channel2 set error \n");
				return -1;
			}
		}			

	}
}

extern int CounterSet(struct Config *pConfig, unsigned char channel)
{
	unsigned char buf[5];
	unsigned int data;
	unsigned int frequence;
	unsigned int highvoltagetime;
	unsigned int reg_channel;
	if(channel == CHANNEL1)
	{
		if(pConfig->stCounterSet.u32EnableCh1 == ENABLE)
		{
			if( (pConfig->stCounterSet.u32FreqCh1 <= pConfig->stCounterSet.u32MaxFreqCh1) && 
					(pConfig->stCounterSet.u32FreqCh1 >= pConfig->stCounterSet.u32MinFreqCh1) )
			{
				frequence = 8000000 / 2 / (pConfig->stCounterSet.u32FreqCh1);	// set frequence 
				if(PRINT_OPEN_COUNTER) printf("frequence = 0x%x \n",frequence);
				if(frequence > 0xffff)
					frequence = 0xffff;				
				buf[0] = REG_FREQUENCE_LOW_CH1;					
				buf[1] = (unsigned char)(frequence & 0x00ff);
				if(PRINT_OPEN_COUNTER) printf("REG_FREQUENCE_LOW_CH1 = 0x%x \n",buf[1]);
				data = write(fd_counter, buf, 5);
				buf[0] = REG_FREQUENCE_HIGH_CH1;
				buf[1] = (unsigned char)((frequence>>8) & 0x00ff);
				if(PRINT_OPEN_COUNTER) printf("REG_FREQUENCE_HIGH_CH2 = 0x%x \n",buf[1]);
				data = write(fd_counter, buf, 5);
			}
			else
			{
				printf("[counter.c] channel1 requence out of range \n");
				return -1;
			}
					
			highvoltagetime = (pConfig->stCounterSet.u32HihtVoltTimeCh1);	// set high voltage time 
			if(highvoltagetime > 0xff)
				highvoltagetime = 0xff;
			buf[0] = REG_HIHG_VOLTAGE_TIME_CH1;
			buf[1] = (unsigned char)(highvoltagetime & 0x00ff);
			data = write(fd_counter, buf, 5);
			
			reg_channel = pConfig->stCounterSet.u32ChannelCh1;				// set channel 
			buf[0] = REG_CHANNEL_CH1;
			buf[1] = (unsigned char)(reg_channel & 0x00ff);
			data = write(fd_counter, buf, 5);
			
			
		}
		else
		{
			printf("[counter.c] Channel1 is disable \n");
			return -1;
		}		
			
	}
	else if(channel == CHANNEL2)
	{
		if(pConfig->stCounterSet.u32EnableCh2 == ENABLE)
		{
			if( (pConfig->stCounterSet.u32FreqCh2 <= pConfig->stCounterSet.u32MaxFreqCh2) && 
					(pConfig->stCounterSet.u32FreqCh2 >= pConfig->stCounterSet.u32MinFreqCh2) )
			{
				frequence = 8000000 / 2 / (pConfig->stCounterSet.u32FreqCh2);
				if(PRINT_OPEN_COUNTER) printf("frequence = 0x%x \n",frequence);
				if(frequence > 0xffff)
					frequence = 0xffff;
				buf[0] = REG_FREQUENCE_LOW_CH2;
				buf[1] = (unsigned char)(frequence & 0x00ff);
				if(PRINT_OPEN_COUNTER) printf("REG_FREQUENCE_LOW_CH1 = 0x%x \n",buf[1]);
				data = write(fd_counter, buf, 5);
				buf[0] = REG_FREQUENCE_HIGH_CH2;
				buf[1] = (unsigned char)((frequence>>8) & 0x00ff);
				if(PRINT_OPEN_COUNTER) printf("REG_FREQUENCE_HIGH_CH2 = 0x%x \n",buf[1]);
				data = write(fd_counter, buf, 5);
			}
			else
			{
				printf("[counter.c] channel2 requence out of range \n");
				return -1;
			}
					
			highvoltagetime = (pConfig->stCounterSet.u32HihtVoltTimeCh2);
			if(highvoltagetime > 0xff)
				highvoltagetime = 0xff;
			buf[0] = REG_HIHG_VOLTAGE_TIME_CH2;
			buf[1] = (unsigned char)(highvoltagetime & 0x00ff);
			data = write(fd_counter, buf, 5);
			reg_channel = pConfig->stCounterSet.u32ChannelCh2;
			buf[0] = REG_CHANNEL_CH2;
			buf[1] = (unsigned char)(reg_channel & 0x00ff);

			data = write(fd_counter, buf, 5);
			
		}
		else
		{
			printf("[counter.c] Channel2 is disable \n");
			return -1;
		}		
			
	}
}

static int CounterVersion(struct Config *pConfig)
{
	unsigned char buf[5];
	unsigned int data;
	buf[0] = REG_VERSION;
	data = read(fd_counter, buf, 5);
	if(data == 0)
	{
		printf("[counter.c] version read \033[31merror\033[0m \n");
		return -1;
	}
		
	if(PRINT_OPEN_COUNTER) printf("[counter.c] version is  V%d.%d \n",(unsigned int)(buf[1]>>4) & 0x0F,(unsigned int)(buf[1]) & 0x0F);
	pConfig->stCounterSet.u32Version = (int)(buf[1]);
	return 0;
}

static int CounterReset(void)
{
	return ioctl(fd_counter, IOCTL_COUNTER_RESET, NULL);
}
extern int CounterPulseRead(unsigned char *data)
{
	unsigned char buf[2];
	unsigned int len;
	buf[0] = REG_PLUS;
	len = read(fd_counter, buf, 2);
	if(len == 0)
	{
		printf("[counter.c] read reg REG_PLUS ERROR \n");
		return -1;
	}
	else
	{
		*data = buf[1];
		return 0;
	}
}





